package com.lry.thompson;

import com.lry.input.Input;

public class ThompsonConstruction {
    private Input input = new Input();
    private MacroHandler macroHandler = null;
	RegularExpressionHandler regularExpr = null;
	private Lexer lexer = null;
	public static boolean print = false;
	public NfaPair nfaPair = new NfaPair();
	private NfaMachine nfaMachine;
	private NfaInterpreter nfaInterpreter;
	private DfaMachine dfaMachine;
	//D [0-9]

	//A [a-z]
	//AD {A}|{D}  间套定义
    public void runMacroExample() throws Exception {
    	System.out.println("Please enter macro definition");
    	
    	input.renewInputBuffer();
    	macroHandler = new MacroHandler(input);
    	macroHandler.printMacs();

    }

    //{D}+

	//{AD}+
    public void runMacroExpandExample() throws Exception {
    	System.out.println("Enter regular expression");
    	input.renewInputBuffer();
    	
    	regularExpr = new RegularExpressionHandler(input, macroHandler);

    	System.out.println("regular expression after expanded: ");
    	for (int i = 0; i < regularExpr.getRegularExpressionCount(); i++) {
    		System.out.println(regularExpr.getRegularExpression(i));	
    	}
    	
    }
    

	private void runLexerExample() {
		lexer = new Lexer(regularExpr);
		int exprCount = 0;
		System.out.println("当前正则解析的正则表达式: " + regularExpr.getRegularExpression(exprCount));
		lexer.advance();

		while (lexer.matchToken(Lexer.Token.END_OF_INPUT) == false) {

			if (lexer.matchToken(Lexer.Token.EOS) == true) {
				System.out.println("解析下一个正则表达式");
				exprCount++;
				System.out.println("当前正则解析的正则表达式: " + regularExpr.getRegularExpression(exprCount));
				lexer.advance();
			}
			else {
				while (!lexer.matchToken(Lexer.Token.EOS)) {
					printLex();
					lexer.advance();
				}
			}
		}
	}

	private void printLex(){
		if(print){
			System.out.println("当前识别字符是: " + (char)lexer.getLexeme());

			if (lexer.matchToken(Lexer.Token.L) != true) {
				System.out.println("当前字符具有特殊含义");

				printMetaCharMeaning(lexer);
			}
			else {
				System.out.println("当前字符是普通字符常量");
			}
		}
	}
	private void printMetaCharMeaning(Lexer lexer) {
		String s = "";
		if (lexer.matchToken(Lexer.Token.ANY)) {
			s = "当前字符是点通配符";
		}

		if (lexer.matchToken(Lexer.Token.AT_BOL)) {
			s = "当前字符是开头匹配符";
		}

		if (lexer.matchToken(Lexer.Token.AT_EOL)) {
			s = "当前字符是末尾匹配符";
		}

		if (lexer.matchToken(Lexer.Token.CCL_END)) {
			s = "当前字符是字符集类结尾括号";
		}

		if (lexer.matchToken(Lexer.Token.CCL_START)) {
			s = "当前字符是字符集类的开始括号";
		}

		if (lexer.matchToken(Lexer.Token.CLOSE_CURLY)) {
			s = "当前字符是结尾大括号";
		}

		if (lexer.matchToken(Lexer.Token.CLOSE_PAREN)) {
			s = "当前字符是结尾圆括号";
		}

		if (lexer.matchToken(Lexer.Token.DASH)) {
			s = "当前字符是横杆";
		}

		if (lexer.matchToken(Lexer.Token.OPEN_CURLY)) {
			s = "当前字符是起始大括号";
		}

		if (lexer.matchToken(Lexer.Token.OPEN_PAREN)) {
			s = "当前字符是起始圆括号";
		}

		if (lexer.matchToken(Lexer.Token.OPTIONAL)) {
			s = "当前字符是单字符匹配符?";
		}

		if (lexer.matchToken(Lexer.Token.OR)) {
			s = "当前字符是或操作符";
		}

		if (lexer.matchToken(Lexer.Token.PLUS_CLOSE)) {
			s = "当前字符是正闭包操作符";
		}

		if (lexer.matchToken(Lexer.Token.CLOSURE)) {
			s = "当前字符是闭包操作符";
		}

		System.out.println(s);
	}


	public void runNfaMachine() throws Exception {
		lexer = new Lexer(regularExpr);
		nfaMachine = new NfaMachine(lexer);
		nfaMachine.expr(nfaPair);
	}

	public void runNfaInterpreter(){
    	nfaInterpreter = new NfaInterpreter(input,nfaPair.start);
    	nfaInterpreter.interpreter();
	}

	public void runDfaMachine(){
    	dfaMachine = new DfaMachine(nfaPair.start, nfaInterpreter,input);
    	dfaMachine.convertNfaToDfa();
    	dfaMachine.interpreter();
	}

	public void runMiniDfaMachine(){
		MiniDfaMachine miniDfaMachine = new MiniDfaMachine(dfaMachine);
		miniDfaMachine.minimize();
		miniDfaMachine.interpreter();
	}

	public static void main(String[] args) throws Exception {
    	ThompsonConstruction construction = new ThompsonConstruction();

    	construction.runMacroExample();// d [^0-9]非数字  D [0-9] A [A-Z] a [a-z]

    	construction.runMacroExpandExample();// {A}+{D}*|{a}?      {A}+{D}+|{a}?

//		construction.runLexerExample();

		construction.runNfaMachine();//生成nfa节点跳转图

		construction.runNfaInterpreter();

		construction.runDfaMachine();

		construction.runMiniDfaMachine();
	}
}
